package com.mysoft.gfyx.marketdevelop.service.impl;


import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.base.Joiner;
import com.mysoft.framework.common.user.User;
import com.mysoft.framework.core.function.authorization.AuthenticationUser;
import com.mysoft.framework.modeling.dto.*;
import com.mysoft.gfyx.common.rpc.opensearch.OpensearchClientFactoryService;
import com.mysoft.gfyx.common.rpc.opensearch.OpensearchClientService;
import com.mysoft.gfyx.common.rpc.opensearch.dto.*;
import com.mysoft.gfyx.common.rpc.opensearch.dto.SearchSupplierRequestDto;
import com.mysoft.gfyx.common.time.TimeService;
import com.mysoft.gfyx.common.util.LogUtil;
import com.mysoft.gfyx.common.ycg.YcgFileService;
import com.mysoft.gfyx.marketdevelop.controller.dto.GetDetailDataRequestDto;
import com.mysoft.gfyx.marketdevelop.dao.OpTelViewHistoryDao;
import com.mysoft.gfyx.marketdevelop.dao.entity.OpTelViewHistory;
import com.mysoft.gfyx.marketdevelop.mip.GetDeveloperDataService;
import com.mysoft.gfyx.marketdevelop.mip.dto.*;
import com.mysoft.gfyx.marketdevelop.mip.dto.TjCustom.SqlApiListResponseDto;
import com.mysoft.gfyx.marketdevelop.mip.dto.TjCustom.SqlApiResponseDto;
import com.mysoft.gfyx.marketdevelop.remoteService.RemoteSubscriptionService;
import com.mysoft.gfyx.marketdevelop.remoteService.dto.GetSubscriptionConfigRequestDto;
import com.mysoft.gfyx.marketdevelop.remoteService.dto.GetSubscriptionConfigResponseDto;
import com.mysoft.gfyx.marketdevelop.service.*;
import com.mysoft.gfyx.marketdevelop.service.dto.PickContactsDto;
import com.mysoft.gfyx.marketdevelop.service.dto.PickProjectsCaseDto;
import com.mysoft.sdk.context.core.ThreadContextHolder;
import jodd.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class ProvinceRadarServiceImp implements ProvinceRadarService {

    @Autowired
    private RemoteSubscriptionService remoteSubscriptionService;

    @Autowired
    private GetDeveloperDataService getDeveloperDataService;

    @Autowired
    private YcgFileService ycgFileService;

    @Autowired
    private TimeService timeService;

    @Autowired
    private CommonService commonService;

    @Autowired
    private SearchService searchService;

    @Autowired
    private DeveloperContactService developerContactService;

    @Autowired
    private OpTelViewHistoryDao opTelViewHistoryDao;

    @Autowired
    private OpensearchClientFactoryService opensearchClientFactoryService;

    @Autowired
    private LogUtil logUtil;

    public FieldsSetting loadRecommendedDeveloperFields() {
        FieldsSetting fieldsSetting = new FieldsSetting();
        fieldsSetting.setIdField("organizing_code");
        fieldsSetting.setFields(new ArrayList<>());
        String groupName = "province_radar_developer";
        fieldsSetting.getFields().add(new DataApiField("developer_name", groupName, "客户名称", FieldType.String));
        fieldsSetting.getFields().add(new DataApiField("organizing_code", groupName, "社会统一信用代码", FieldType.String));
        fieldsSetting.getFields().add(new DataApiField("developer_logo", groupName, "开发商Logo", FieldType.Picture));
//        fieldsSetting.getFields().add(new DataApiField("special_period", groupName, "时间段", FieldType.String));
        fieldsSetting.getFields().add(new DataApiField("province_code", groupName, "省份编码", FieldType.String));

        fieldsSetting.getFields().add(new DataApiField("company_type_label", groupName, "企业类型标签", FieldType.String));
        fieldsSetting.getFields().add(new DataApiField("listed_enterprises_label", groupName, "上市标签", FieldType.String));
        fieldsSetting.getFields().add(new DataApiField("business_status_label", groupName, "营业状态标签", FieldType.String));
        fieldsSetting.getFields().add(new DataApiField("developer_top_100_label", groupName, "百强标签", FieldType.String));
        fieldsSetting.getFields().add(new DataApiField("high_project_customers_label", groupName, "高端项目标签", FieldType.String));
        fieldsSetting.getFields().add(new DataApiField("developer_activity_label", groupName, "活跃标签", FieldType.String));
        fieldsSetting.getFields().add(new DataApiField("is_new_area_expand_label", groupName, "新区域扩展标签", FieldType.String));
        fieldsSetting.getFields().add(new DataApiField("is_new_land_usage_expand_label", groupName, "新土地类型扩展标签", FieldType.String));
        fieldsSetting.getFields().add(new DataApiField("is_new_decorate_expand_label", groupName, "新精装标签", FieldType.String));
        fieldsSetting.getFields().add(new DataApiField("is_ycg_certification", groupName, "平台认证", FieldType.String));
        fieldsSetting.getFields().add(new DataApiField("ycg_exhibition", groupName, "供需对接会", FieldType.String));
        fieldsSetting.getFields().add(new DataApiField("is_new", groupName, "是否有新动态", FieldType.String));
        fieldsSetting.getFields().add(new DataApiField("developer_score", groupName, "好客户得分", FieldType.Int));

        return fieldsSetting;
    }

    public ListDataResult loadRecommendedDeveloperData(LoadDataParams options) {
        Object contextPageSize = options.getOptions().getContext().get("page_size");
        int pageSize = contextPageSize == null ? options.getPageSize() : Integer.parseInt(contextPageSize.toString());

        RecommendedDeveloperRequestDto dto = new RecommendedDeveloperRequestDto();
        dto.addFilterByLoadDataApi(options.getOptions().getFilters());
        dto.setArea_code(commonService.checkAreaProfit(dto.getArea_code()));
        dto.setPage(options.getPageIndex() + 1);
        dto.setPage_size(pageSize);

        GetSubscriptionConfigRequestDto getSubscriptionConfigRequestDto = new GetSubscriptionConfigRequestDto();
        getSubscriptionConfigRequestDto.setType(GetSubscriptionConfigRequestDto.SubscriptionType.RadarSubscription);
        GetSubscriptionConfigResponseDto config = remoteSubscriptionService.getSubscriptionConfig(getSubscriptionConfigRequestDto);
        if (config != null) {
            dto.setKeyword(config.getProjectKeywords());
            dto.setLand_usage(config.getLandUsage());
            dto.setProject_label(config.getProjectType());
            dto.setFitment_fee_label(config.getFitmentType());
        }

        OpensearchClientService service = opensearchClientFactoryService.getOpensearchService();
        OpenSearchListResponseDto res = service.recommendedDeveloperList(dto);

        ListDataResult result = new ListDataResult();

        if (res == null || res.getData() == null || res.getData().getTotal() == 0) {
            result.setTotal(0);
            result.setData(new ArrayList<>());
            return result;
        }
        HashSet<String> creditCodeList = new HashSet<>();
        HashSet<String> companyNameList = new HashSet<>();
        res.getData().getList().forEach(d -> {
            if (d.get("organizing_code") != null && !d.get("organizing_code").equals("")) {
                creditCodeList.add(d.get("organizing_code").toString());
            }
            if (d.get("developer_name") != null && !d.get("developer_name").equals("")) {
                companyNameList.add(d.get("developer_name").toString());
            }
        });

        //调用opensearch,获取采购商得分
        HashMap<String, Integer> developerScoreMap = new HashMap<>();
        GetDeveloperScoreRequestDto scoreRequestDto = new GetDeveloperScoreRequestDto();
        scoreRequestDto.setOrganizing_code(Joiner.on(",").join(creditCodeList));
        scoreRequestDto.setSubscription_land_usage(dto.getLand_usage());
        scoreRequestDto.setSubscription_project_type(dto.getProject_label());
        OpenSearchSingleListResponseDto responseDto = service.getDeveloperScore(scoreRequestDto);
        if (responseDto != null && responseDto.getData() != null) {
            responseDto.getData().forEach(item -> {
                if (item.get("developer_score") != null && item.get("organizing_code") != null && item.get("organizing_code") != "") {
                    developerScoreMap.put((String) item.get("organizing_code"), (Integer) item.get("developer_score"));
                }
            });
        }

        HashMap<String, List<Object>> companyName2Contacts = new HashMap<>();
        HashMap<String, List<Object>> organizingCode2Contacts = new HashMap<>();
        if (creditCodeList.size() != 0 || companyNameList.size() != 0) {
            // 获取联系人信息
            RadarContactRequestDto radarContactRequestDto = new RadarContactRequestDto();
            if (config != null) {
                radarContactRequestDto.setBid_keyword(config.getBidKeywords());
                radarContactRequestDto.setSupplier_keyword(config.getSupplierKeywords());
                radarContactRequestDto.setSubscript_area_code(config.getArea());
            }
            radarContactRequestDto.setIs_developer("1");
            radarContactRequestDto.setOrganizing_code(String.join(",", creditCodeList));
            radarContactRequestDto.setCompany_name(String.join(",", companyNameList));
            OpenSearchSingleListResponseDto contactRes = service.radarContact(radarContactRequestDto);
            this.addContactViewTimes(contactRes, companyName2Contacts, organizingCode2Contacts);
        }

        List<String> idList = new ArrayList<>();
        res.getData().getList().forEach(d -> {
            if (d.get("organizing_code") != null) {
                idList.add(d.get("organizing_code").toString());
            }
            // 处理Logo
            if (d.get("developer_logo") != null && d.get("developer_id") != null) {
                d.put("developer_logo", ycgFileService.getEnterpriseLogo(d.get("developer_id").toString(), d.get("developer_logo").toString()));
            }

            if (d.get("organizing_code") != null) {
                Integer developerScore = developerScoreMap.get(d.get("organizing_code").toString());
                d.put("developer_score", developerScore);
            } else {
                d.put("developer_score", "");
            }
            d.put("picked_contacts", this.pickedContacts(companyName2Contacts, organizingCode2Contacts, d.getOrDefault("developer_name", ""), d.getOrDefault("organizing_code", "")));
        });
        //数据状态
        Map<String, String> opptyStatus = commonService.getOpptyStatusBatch(CommonService.BigDataType.DEVELOPER.toString(), idList);
        res.getData().getList().forEach(r -> {
            if (r.get("organizing_code") != null && opptyStatus.containsKey(r.get("organizing_code").toString())) {
                r.put("oppty_status", opptyStatus.get(r.get("organizing_code").toString()));
            } else {
                r.put("oppty_status", "");
            }
        });

        result.setTotal(res.getData().getTotal());
        result.setData(res.getData().getList());
        return result;
    }

    protected void addContactViewTimes(OpenSearchSingleListResponseDto contactRes, HashMap<String, List<Object>> companyName2Contacts, HashMap<String, List<Object>> organizingCode2Contacts) {
        if (contactRes != null && contactRes.getData() != null) {
            Set<String> mobileSet = new HashSet<>();
            contactRes.getData().forEach(contact -> {
                if (contact != null && contact.get("phone_number") != null) {
                    mobileSet.add(contact.get("phone_number").toString());
                }
            });
            Map<String, OpTelViewHistory> opTelViewHistoryMap = getTelViewHistories(mobileSet);

            contactRes.getData().forEach(contact -> {
                if (contact != null) {
                    if (contact.get("phone_number") != null) {
                        if (opTelViewHistoryMap.containsKey(contact.get("phone_number").toString())) {
                            OpTelViewHistory opTelViewHistory = opTelViewHistoryMap.get(contact.get("phone_number").toString());
                            contact.put("view_times", opTelViewHistory.getViewTimes());
                        } else {
                            contact.put("view_times", 0);
                            if (contact.get("phone_number").toString().length() > 7) {
                                contact.put("phone_number", contact.get("phone_number").toString().substring(0, 3) + "****" + contact.get("phone_number").toString().substring(7));
                            }
                        }

                    }
                    if (contact.get("company_name") != null) {
                        List<Object> contactList = companyName2Contacts.get(contact.get("company_name").toString());
                        if (contactList == null) {
                            contactList = new ArrayList<>();
                            contactList.add(contact);
                        } else {
                            contactList.add(contact);
                        }
                        companyName2Contacts.put(contact.get("company_name").toString(), contactList);
                    }
                    if (contact.get("organizing_code") != null) {
                        List<Object> contactList = organizingCode2Contacts.get(contact.get("organizing_code").toString());
                        if (contactList == null) {
                            contactList = new ArrayList<>();
                            contactList.add(contact);
                        } else {
                            contactList.add(contact);
                        }
                        organizingCode2Contacts.put(contact.get("organizing_code").toString(), contactList);
                    }
                }
            });
        }
    }

    protected void loadTelViewHistory(List<PickContactsDto> contactsDto, Map<String, OpTelViewHistory> opTelViewHistoryMap) {
        contactsDto.forEach(pickContactsDto -> {
            if (opTelViewHistoryMap.containsKey(pickContactsDto.getMobile()))
                pickContactsDto.setViewTimes(opTelViewHistoryMap.get(pickContactsDto.getMobile()).getViewTimes());
        });
    }

    public Map<String, OpTelViewHistory> getTelViewHistories(Set<String> mobiles) {
        Map<String, OpTelViewHistory> opTelViewHistoryMap = new HashMap<>();
        if (mobiles.size() == 0) return opTelViewHistoryMap;

        User authenticationUser = ThreadContextHolder.getInstance().get(AuthenticationUser.class);

        QueryWrapper<OpTelViewHistory> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("CreatedGUID", authenticationUser.getUserId());
        queryWrapper.in("TelNumber", mobiles);

        List<OpTelViewHistory> opTelViewHistories = opTelViewHistoryDao.selectList(queryWrapper);


        if (opTelViewHistories == null || opTelViewHistories.size() == 0) {
            return opTelViewHistoryMap;
        }

        opTelViewHistories.forEach(opTelViewHistory -> {
            opTelViewHistoryMap.put(opTelViewHistory.getTelNumber(), opTelViewHistory);
        });

        return opTelViewHistoryMap;
    }

    public FieldsSetting loadRecommendedOpportunityFields() {
        //硬编码的获取字段逻辑
        FieldsSetting fieldsSetting = new FieldsSetting();
        fieldsSetting.setIdField("id");
        fieldsSetting.setFields(new ArrayList<>());
        String groupName = "province_radar_opportunity";
        fieldsSetting.getFields().add(new DataApiField("id", groupName, "ID", FieldType.String));
        fieldsSetting.getFields().add(new DataApiField("uid", groupName, "UID", FieldType.String));
        fieldsSetting.getFields().add(new DataApiField("developer_name", groupName, "招标单位", FieldType.String));
        fieldsSetting.getFields().add(new DataApiField("organizing_code", groupName, "社会统一信用代码", FieldType.String));
        fieldsSetting.getFields().add(new DataApiField("title", groupName, "标题", FieldType.String));
        fieldsSetting.getFields().add(new DataApiField("publish_time", groupName, "发布时间", FieldType.String));
        fieldsSetting.getFields().add(new DataApiField("company_type", groupName, "企业类型", FieldType.String));
        fieldsSetting.getFields().add(new DataApiField("data_source", groupName, "信息类型", FieldType.String));
        fieldsSetting.getFields().add(new DataApiField("data_source_code", groupName, "信息类型Code", FieldType.String));
        fieldsSetting.getFields().add(new DataApiField("end_time", groupName, "截止时间", FieldType.String));
        fieldsSetting.getFields().add(new DataApiField("province_code", groupName, "省份Code", FieldType.String));
        fieldsSetting.getFields().add(new DataApiField("city_code", groupName, "城市Code", FieldType.String));
        fieldsSetting.getFields().add(new DataApiField("province", groupName, "省份", FieldType.String));
        fieldsSetting.getFields().add(new DataApiField("city", groupName, "城市", FieldType.String));
        fieldsSetting.getFields().add(new DataApiField("bidding_service_category", groupName, "服务分类", FieldType.String));
        fieldsSetting.getFields().add(new DataApiField("status", groupName, "采购状态", FieldType.String));
        fieldsSetting.getFields().add(new DataApiField("owner", groupName, "招标负责人", FieldType.String));
        fieldsSetting.getFields().add(new DataApiField("owner_mobile", groupName, "招标负责人电话", FieldType.String));
        fieldsSetting.getFields().add(new DataApiField("phone_type", groupName, "招标负责人电话类型", FieldType.String));
        fieldsSetting.getFields().add(new DataApiField("project_name", groupName, "项目名称", FieldType.String));
        fieldsSetting.getFields().add(new DataApiField("has_added", groupName, "是否已添加过线索", FieldType.Int));
        fieldsSetting.getFields().add(new DataApiField("purchase_amount", groupName, "采购预算", FieldType.String));
        fieldsSetting.getFields().add(new DataApiField("purchase_demand_cnt_1year", groupName, "关联招标", FieldType.String));
        fieldsSetting.getFields().add(new DataApiField("cooperation_enterprise_cnt", groupName, "合作单位", FieldType.String));
        fieldsSetting.getFields().add(new DataApiField("is_new", groupName, "是否为新数据", FieldType.String));

        // 返回
        return fieldsSetting;
    }


    public ListDataResult loadRecommendedOpportunityData(LoadDataParams options) {
        Object contextPageSize = options.getOptions().getContext().get("page_size");
        int pageSize = contextPageSize == null ? options.getPageSize() : Integer.parseInt(contextPageSize.toString());

        PurchaseSubscriptionRequestDto dto = new PurchaseSubscriptionRequestDto();
        dto.setPage(options.getPageIndex() + 1);
        dto.setPage_size(pageSize);
        dto.addFilterByLoadDataApi(options.getOptions().getFilters());
        dto.setArea(commonService.checkAreaProfit(dto.getArea()));
        dto.setSource("trading_center,website_bid");
        dto.setNeed_org_code("1");
        // 获取关键词
        GetSubscriptionConfigRequestDto getSubscriptionConfigRequestDto = new GetSubscriptionConfigRequestDto();
        getSubscriptionConfigRequestDto.setType(GetSubscriptionConfigRequestDto.SubscriptionType.RadarSubscription);
        GetSubscriptionConfigResponseDto config = remoteSubscriptionService.getSubscriptionConfig(getSubscriptionConfigRequestDto);
        if (config != null) dto.setKeyword(config.getBidKeywords());

        OpensearchClientService service = opensearchClientFactoryService.getOpensearchService();
        //请求opensearch,post请求,避免入参过长导致get请求超长
        OpenSearchListResponseDto res = service.purchaseSubscription(dto);
        ListDataResult result = new ListDataResult();
        if (res == null || res.getData() == null || res.getData().getList() == null) {
            result.setData(new ArrayList<>());
            result.setTotal(0);
            return result;
        }

        List<String> companyNameList = new ArrayList<>();
        List<String> organizingCodeList = new ArrayList<>();
        HashMap<String, List<Object>> companyName2Contacts = new HashMap<>();
        HashMap<String, List<Object>> organizingCode2Contacts = new HashMap<>();
        res.getData().getList().forEach(r -> {
            if (r.get("developer_name") != null && !r.get("developer_name").equals("")) {
                companyNameList.add(r.get("developer_name").toString());
            }
            if (r.get("organizing_code") != null && !r.get("organizing_code").equals("")) {
                organizingCodeList.add(r.get("organizing_code").toString());
            }
        });

        if (companyNameList.size() != 0 || organizingCodeList.size() != 0) {
            // 获取联系人信息
            Set<String> mobileSet = new HashSet<>();
            RadarContactRequestDto radarContactRequestDto = new RadarContactRequestDto();
            if (config != null) {
                radarContactRequestDto.setBid_keyword(config.getBidKeywords());
                radarContactRequestDto.setSupplier_keyword(config.getSupplierKeywords());
                radarContactRequestDto.setSubscript_area_code(config.getArea());
            }
            radarContactRequestDto.setIs_developer("1");

            radarContactRequestDto.setOrganizing_code(String.join(",", organizingCodeList));
            radarContactRequestDto.setCompany_name(String.join(",", companyNameList));
            OpenSearchSingleListResponseDto contactRes = service.radarContact(radarContactRequestDto);
            this.addContactViewTimes(contactRes, companyName2Contacts, organizingCode2Contacts);
        }

        List<String> idList = new ArrayList<>();
        res.getData().getList().forEach(r -> {
            if (r.get("id") != null) {
                idList.add(r.get("id").toString());
            }
            // 处理 logo
            if (r.get("developer_id") != null && r.get("developer_logo") != null) {
                r.put("developer_logo", ycgFileService.getEnterpriseLogo(r.get("developer_id").toString(), r.get("developer_logo").toString()));
            }

            if (r.get("projects") != null) {
                // 处理项目名称
                r.put("project_name", searchService.spellProjectName(r.get("projects")));

                // 处理省市
                OpportunityProjectDto projectDto = searchService.getProvinceAndCityFromProject(r.get("projects"));
                r.put("city", projectDto.getCity());
                r.put("province", projectDto.getProvince());
            }

            //取联系人数据
            r.put("picked_contacts", this.pickedContacts(companyName2Contacts, organizingCode2Contacts, r.getOrDefault("developer_name", ""), r.getOrDefault("organizing_code", "")));
        });

        //数据状态
        Map<String, String> opptyStatus = commonService.getOpptyStatusBatch(CommonService.BigDataType.PURCHASE.toString(), idList);
        res.getData().getList().forEach(r -> {
            if (r.get("id") != null && opptyStatus.containsKey(r.get("id").toString())) {
                r.put("oppty_status", opptyStatus.get(r.get("id").toString()));
            } else {
                r.put("oppty_status", "");
            }
        });

        result.setData(res.getData().getList());
        result.setTotal(res.getData().getTotal());

        return result;
    }

    protected String pickedContacts(HashMap<String, List<Object>> companyName2Contacts, HashMap<String, List<Object>> organizingCode2Contacts, Object companyName, Object organizingCode) {
        List<Object> contactList = new ArrayList<>();
        if (organizingCode != null && !organizingCode.equals("") && organizingCode2Contacts.containsKey(organizingCode.toString())) {
            contactList = organizingCode2Contacts.get(organizingCode.toString());
        } else if (companyName != null && !companyName.equals("") && companyName2Contacts.containsKey(companyName.toString())) {
            contactList = companyName2Contacts.get(companyName.toString());
        }
        return JSON.toJSONString(contactList);
    }

    protected Set<String> getPurchaseMobile(SqlApiListResponseDto sqlApiResponseDto, List<Map<String, Object>> pContacts) {
        Set<String> mobileSet = new HashSet<>();
        pContacts.forEach(pc -> {
            mobileSet.add(pc.get("mobile").toString());
        });

        if (sqlApiResponseDto.getData() != null && sqlApiResponseDto.getData().size() > 0) {
            sqlApiResponseDto.getData().forEach(pc -> {
                if (pc.get("contact_tel") != null) {
                    mobileSet.add(pc.get("contact_tel").toString());
                }
            });
        }
        return mobileSet;
    }

    protected PickContactsDto makeContact(Map<String, Object> pc) {
        PickContactsDto contactsDto = new PickContactsDto();
        contactsDto.setCompany_category(pc.get("company_category").toString());
        if (pc.get("company_category").toString().equals("开发商")) {
            contactsDto.setWeight(contactsDto.getWeight() + 1);
            if (pc.get("developer_company_name") != null)
                contactsDto.setCompany(pc.get("developer_company_name").toString());
        } else {
            if (pc.get("supplier_company_name") != null)
                contactsDto.setCompany(pc.get("supplier_company_name").toString());
        }
        if (pc.get("contact_person") != null) contactsDto.setOwner(pc.get("contact_person").toString());
        if (pc.get("contact_person") != null && pc.get("contact_person").toString().length() >= 1) {
            contactsDto.setFirst_name(pc.get("contact_person").toString().substring(0, 1));
        }
        if (pc.get("contact_tel") != null) contactsDto.setMobile(pc.get("contact_tel").toString());
        if (pc.get("contact_tel") != null && pc.get("contact_tel").toString().length() > 7) {
            contactsDto.setMobile_hide(pc.get("contact_tel").toString().substring(0, 3) + "****" + pc.get("contact_tel").toString().substring(7));
        }
        if (pc.get("supplier_organizing_code") != null)
            contactsDto.setSupplier_organizing_code(pc.get("supplier_organizing_code").toString());
        if (pc.get("updated_time") != null) contactsDto.setUpdated_time(pc.get("updated_time").toString());
        if (pc.get("id") != null) contactsDto.setId(pc.get("id").toString());
        return contactsDto;
    }


    public FieldsSetting loadRecommendedProjectsFields() {
        FieldsSetting fieldsSetting = new FieldsSetting();
        fieldsSetting.setIdField("id");
        fieldsSetting.setFields(new ArrayList<>());
        String groupName = "province_radar_project";
        fieldsSetting.getFields().add(new DataApiField("uuid", groupName, "id", FieldType.String));
        fieldsSetting.getFields().add(new DataApiField("id", groupName, "id", FieldType.String));
        fieldsSetting.getFields().add(new DataApiField("developer_name", groupName, "客户名称", FieldType.String));
        fieldsSetting.getFields().add(new DataApiField("organizing_code", groupName, "社会统一信用代码", FieldType.String));
        fieldsSetting.getFields().add(new DataApiField("developer_logo", groupName, "开发商Logo", FieldType.Picture));
        fieldsSetting.getFields().add(new DataApiField("start_time", groupName, "开始时间", FieldType.String));
        fieldsSetting.getFields().add(new DataApiField("end_time", groupName, "结束时间", FieldType.String));
        fieldsSetting.getFields().add(new DataApiField("province_code", groupName, "省份编码", FieldType.String));
        fieldsSetting.getFields().add(new DataApiField("data_type", groupName, "数据类型", FieldType.String));

        fieldsSetting.getFields().add(new DataApiField("land_title", groupName, "土地标题", FieldType.String));
        fieldsSetting.getFields().add(new DataApiField("take_land_price", groupName, "成交价", FieldType.String));
        fieldsSetting.getFields().add(new DataApiField("land_usage_label", groupName, "土地类型", FieldType.String));
        fieldsSetting.getFields().add(new DataApiField("unit_price", groupName, "楼面单价", FieldType.String));

        fieldsSetting.getFields().add(new DataApiField("project_title", groupName, "项目标题", FieldType.String));
        fieldsSetting.getFields().add(new DataApiField("all_invest", groupName, "总投资", FieldType.String));
        fieldsSetting.getFields().add(new DataApiField("prj_type_num", groupName, "工程类型", FieldType.String));

        fieldsSetting.getFields().add(new DataApiField("picked_contacts", groupName, "联系人", FieldType.String));
        fieldsSetting.getFields().add(new DataApiField("fitment_fee_label", groupName, "装修类型", FieldType.String));
        fieldsSetting.getFields().add(new DataApiField("is_price_gt_avg", groupName, "高端项目", FieldType.String));
        fieldsSetting.getFields().add(new DataApiField("land_usage_label_v2", groupName, "土地用途", FieldType.String));
        fieldsSetting.getFields().add(new DataApiField("is_new", groupName, "是否为新数据", FieldType.String));
        return fieldsSetting;
    }

    /**
     * 推荐项目（数据来源es）
     *
     * @param options
     * @return
     */
    public ListDataResult loadRecommendedProjectsData(LoadDataParams options) {
        Object contextPageSize = options.getOptions().getContext().get("page_size");
        int pageSize = contextPageSize == null ? options.getPageSize() : Integer.parseInt(contextPageSize.toString());

        SubscriptRadarProjectRequestDto dto = new SubscriptRadarProjectRequestDto();
        dto.addFilterByLoadDataApi(options.getOptions().getFilters());
        dto.setArea_code(commonService.checkAreaProfit(dto.getArea_code()));
        dto.setPage(options.getPageIndex() + 1);
        dto.setPage_size(pageSize);

        GetSubscriptionConfigRequestDto getSubscriptionConfigRequestDto = new GetSubscriptionConfigRequestDto();
        getSubscriptionConfigRequestDto.setType(GetSubscriptionConfigRequestDto.SubscriptionType.RadarSubscription);
        GetSubscriptionConfigResponseDto config = remoteSubscriptionService.getSubscriptionConfig(getSubscriptionConfigRequestDto);
        if (config != null) {
            dto.setLand_usage_label(config.getLandUsage());
            dto.setProject_label(config.getProjectType());
            dto.setFitment_fee_label(config.getFitmentType());
            dto.setIs_price_gt_avg(config.getProjectTag());
            dto.setKeyword(config.getProjectKeywords());
        }

        OpensearchClientService service = opensearchClientFactoryService.getOpensearchService();
        OpenSearchListResponseDto data = service.subscriptRadarProject(dto);

        ListDataResult result = new ListDataResult();

        if (data == null || data.getData() == null || data.getData().getTotal() == 0) {
            result.setTotal(0);
            result.setData(new ArrayList<>());
            return result;
        }

        // 获取联系人
        HashSet<String> companyNameList = new HashSet<>();
        HashSet<String> organizingCodeList = new HashSet<>();
        data.getData().getList().forEach(r -> {
            if (r.get("developer_name") != null && !r.get("developer_name").equals("")) {
                companyNameList.add(r.get("developer_name").toString());
            }
            if (r.get("organizing_code") != null && !r.get("organizing_code").equals("")) {
                organizingCodeList.add(r.get("organizing_code").toString());
            }
        });

        HashMap<String, List<Object>> companyName2Contacts = new HashMap<>();
        HashMap<String, List<Object>> organizingCode2Contacts = new HashMap<>();
        if (organizingCodeList.size() != 0 || companyNameList.size() != 0) {
            RadarContactRequestDto radarContactRequestDto = new RadarContactRequestDto();
            if (config != null) {
                radarContactRequestDto.setBid_keyword(config.getBidKeywords());
                radarContactRequestDto.setSupplier_keyword(config.getSupplierKeywords());
                radarContactRequestDto.setSubscript_area_code(config.getArea());
            }
            radarContactRequestDto.setIs_developer("1");
            radarContactRequestDto.setOrganizing_code(String.join(",", organizingCodeList));
            radarContactRequestDto.setCompany_name(String.join(",", companyNameList));

            OpenSearchSingleListResponseDto contactRes = service.radarContact(radarContactRequestDto);
            this.addContactViewTimes(contactRes, companyName2Contacts, organizingCode2Contacts);
        }

        List<String> idList = new ArrayList<>();
        data.getData().getList().forEach(r -> {
            if (r.get("id") != null) {
                idList.add(r.get("id").toString());
            }
            // 处理 logo
            if (r.get("developer_id") != null && r.get("developer_logo") != null) {
                r.put("developer_logo", ycgFileService.getEnterpriseLogo(r.get("developer_id").toString(), r.get("developer_logo").toString()));
            }

            // 当土地的时候，建模无法读取land_title，可能是bug，所以这里就写到另一个字段里面
            if (r.get("land_title") != null && !r.get("land_title").equals(""))
                r.put("project_title", r.get("land_title").toString());

            // 当项目的时候，fitment_fee_label，可能是bug，所以这里就写到另一个字段里面
            if (r.get("fitment_fee_label") != null && !r.get("fitment_fee_label").equals(""))
                r.put("contract_date", r.get("fitment_fee_label").toString());

            r.put("picked_contacts", this.pickedContacts(companyName2Contacts, organizingCode2Contacts, r.getOrDefault("developer_name", ""), r.getOrDefault("organizing_code", "")));

            if (r.get("land_usage_label_v2") != null) {
                r.put("land_usage_label_v2", JSON.toJSONString(r.get("land_usage_label_v2")));
            }
        });
        //数据状态
        Map<String, String> opptyStatus = commonService.getOpptyStatusBatch(CommonService.BigDataType.RADARPROJECT.toString(), idList);
        data.getData().getList().forEach(r -> {
            if (r.get("id") != null && opptyStatus.containsKey(r.get("id").toString())) {
                r.put("oppty_status", opptyStatus.get(r.get("id").toString()));
            } else {
                r.put("oppty_status", "");
            }
        });

        result.setData(data.getData().getList());
        result.setTotal(data.getData().getTotal());
        return result;
    }

    public FieldsSetting loadRecommendedSuppliersFields() {
        FieldsSetting fieldsSetting = new FieldsSetting();
        fieldsSetting.setIdField("organizing_code");
        fieldsSetting.setFields(new ArrayList<>());
        String groupName = "province_radar_supplier";
        fieldsSetting.getFields().add(new DataApiField("supplier_name", groupName, "客户名称", FieldType.String));
        fieldsSetting.getFields().add(new DataApiField("organizing_code", groupName, "社会统一信用代码", FieldType.String));
        fieldsSetting.getFields().add(new DataApiField("developer_logo", groupName, "开发商Logo", FieldType.Picture));
        fieldsSetting.getFields().add(new DataApiField("start_time", groupName, "开始时间", FieldType.String));
        fieldsSetting.getFields().add(new DataApiField("end_time", groupName, "结束时间", FieldType.String));
        fieldsSetting.getFields().add(new DataApiField("province_code", groupName, "省份编码", FieldType.String));

        fieldsSetting.getFields().add(new DataApiField("province", groupName, "省份", FieldType.String));
        fieldsSetting.getFields().add(new DataApiField("city", groupName, "城市", FieldType.String));

        fieldsSetting.getFields().add(new DataApiField("project_number", groupName, "相关案例数量", FieldType.String));

        fieldsSetting.getFields().add(new DataApiField("project_info_json", groupName, "相关案例", FieldType.String));
        fieldsSetting.getFields().add(new DataApiField("picked_contacts", groupName, "联系人", FieldType.String));
        fieldsSetting.getFields().add(new DataApiField("is_new", groupName, "是否有新合作", FieldType.String));
        return fieldsSetting;
    }


    public ListDataResult loadRecommendedSuppliersData(LoadDataParams options) {
        Object contextPageSize = options.getOptions().getContext().get("page_size");
        int pageSize = contextPageSize == null ? options.getPageSize() : Integer.parseInt(contextPageSize.toString());

        SearchSupplierRequestDto dto = new SearchSupplierRequestDto();
        dto.setPage(options.getPageIndex() + 1);
        dto.setPage_size(pageSize);
        dto.addFilterByLoadDataApi(options.getOptions().getFilters());
        dto.setProject_area(commonService.checkAreaProfit(dto.getArea()));

        //推荐供应商只匹配项目地址
        dto.setArea("");
        dto.setProvince_code("");
        dto.setCity_code("");

        // 获取关键词
        GetSubscriptionConfigRequestDto getSubscriptionConfigRequestDto = new GetSubscriptionConfigRequestDto();
        getSubscriptionConfigRequestDto.setType(GetSubscriptionConfigRequestDto.SubscriptionType.RadarSubscription);
        GetSubscriptionConfigResponseDto config = remoteSubscriptionService.getSubscriptionConfig(getSubscriptionConfigRequestDto);
        if (config != null) dto.setKeyword(config.getSupplierKeywords());

        OpensearchClientService service = opensearchClientFactoryService.getOpensearchService();
        OpenSearchListResponseDto res = service.searchSupplier(dto);

        ListDataResult result = new ListDataResult();
        if (res.getData() == null || res.getData().getList() == null) {
            result.setData(new ArrayList<>());
            result.setTotal(0);
            return result;
        }

        // 获取联系人
        HashSet<String> companyNameList = new HashSet<>();
        HashSet<String> organizingCodeList = new HashSet<>();
        res.getData().getList().forEach(r -> {
            if (r.get("supplier_name") != null && !r.get("supplier_name").equals("")) {
                companyNameList.add(r.get("supplier_name").toString());
            }
            if (r.get("organizing_code") != null && !r.get("organizing_code").equals("")) {
                organizingCodeList.add(r.get("organizing_code").toString());
            }
        });

        HashMap<String, List<Object>> companyName2Contacts = new HashMap<>();
        HashMap<String, List<Object>> organizingCode2Contacts = new HashMap<>();
        if (organizingCodeList.size() != 0 || companyNameList.size() != 0) {
            RadarContactRequestDto radarContactRequestDto = new RadarContactRequestDto();
            if (config != null) {
                radarContactRequestDto.setBid_keyword(config.getBidKeywords());
                radarContactRequestDto.setSupplier_keyword(config.getSupplierKeywords());
                radarContactRequestDto.setSubscript_area_code(config.getArea());
            }
            radarContactRequestDto.setIs_supplier("1");
            radarContactRequestDto.setOrganizing_code(String.join(",", organizingCodeList));
            radarContactRequestDto.setCompany_name(String.join(",", companyNameList));
            OpenSearchSingleListResponseDto contactRes = service.radarContact(radarContactRequestDto);
            this.addContactViewTimes(contactRes, companyName2Contacts, organizingCode2Contacts);
        }

        List<String> idList = new ArrayList<>();
        res.getData().getList().forEach(r -> {
            if (r.get("organizing_code") != null) {
                idList.add(r.get("organizing_code").toString());
            }
            // 处理 logo
            if (r.get("supplier_id") != null && r.get("supplier_logo") != null) {
                r.put("developer_logo", ycgFileService.getEnterpriseLogo(r.get("supplier_id").toString(), r.get("supplier_logo").toString()));
            }
            // 项目
            if (r.get("projects") != null) {
                List<PickProjectsCaseDto> pickProjectsCaseDtos = sortProjectsObject(r.get("projects"), dto.getProject_start_time(), dto.getProject_area());
                r.put("project_info_json", JSON.toJSONString(pickProjectsCaseDtos));
                r.put("projects", JSON.toJSONString(r.get("projects")));
                r.put("coop_cnt", pickProjectsCaseDtos.size());
            }

            r.put("picked_contacts", this.pickedContacts(companyName2Contacts, organizingCode2Contacts, r.getOrDefault("supplier_name", ""), r.getOrDefault("organizing_code", "")));
        });
        //数据状态
        Map<String, String> opptyStatus = commonService.getOpptyStatusBatch(CommonService.BigDataType.SUPPLIER.toString(), idList);
        res.getData().getList().forEach(r -> {
            if (r.get("organizing_code") != null && opptyStatus.containsKey(r.get("organizing_code").toString())) {
                r.put("oppty_status", opptyStatus.get(r.get("organizing_code").toString()));
            } else {
                r.put("oppty_status", "");
            }
        });

        result.setData(res.getData().getList());
        result.setTotal(res.getData().getTotal());
        return result;
    }

    protected List<PickProjectsCaseDto> sortProjectsObject(Object projectObject, String projectStartTime, String areas) {
        List<PickProjectsCaseDto> pickedProjects = new ArrayList<>();

        ArrayList<LinkedHashMap<String, Object>> ts;
        if (projectObject == null) {
            return null;
        }


        ts = (ArrayList<LinkedHashMap<String, Object>>) projectObject;

        List<String> areaList;
        if (areas != null && !areas.equals("")) {
            areaList = new ArrayList<>(Arrays.asList(areas.split(",")));
        } else {
            areaList = new ArrayList<>();
        }

        ts.forEach(t -> {
            PickProjectsCaseDto pickProjectsCaseDto = new PickProjectsCaseDto();
            pickProjectsCaseDto.setProject_name(t.get("project_name").toString());
            pickProjectsCaseDto.setAmount(t.get("amount").toString());
            pickProjectsCaseDto.setDate(t.get("date").toString());

            try {
                Date pd = timeService.parseDateStr(t.get("date").toString());
                Date ld = timeService.parseDateStr(projectStartTime);
                boolean suitableTime = pd.getTime() >= ld.getTime();
                boolean suitableProvince = false;
                if (t.get("province_code") != null && t.get("city_code") != null) {
                    suitableProvince = areaList.contains(t.get("province_code").toString()) || areaList.contains(t.get("city_code").toString());
                }

                if (suitableProvince && suitableTime) pickedProjects.add(pickProjectsCaseDto);
            } catch (RuntimeException e) {
            }

        });

        Collections.sort(pickedProjects);
        return pickedProjects;
    }

    public void viewTelNumber(String telNumber) {
        User authenticationUser = ThreadContextHolder.getInstance().get(AuthenticationUser.class);

        QueryWrapper<OpTelViewHistory> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("CreatedGUID", authenticationUser.getUserId());
        queryWrapper.eq("TelNumber", telNumber);

        List<OpTelViewHistory> opTelViewHistories = opTelViewHistoryDao.selectList(queryWrapper);

        if (opTelViewHistories.size() == 0) {
            OpTelViewHistory opTelViewHistoryNew = new OpTelViewHistory();
            opTelViewHistoryNew.setOpTelViewHistoryGUID(UUID.randomUUID());
            opTelViewHistoryNew.setTelNumber(telNumber);
            opTelViewHistoryNew.setViewTimes(1);
            opTelViewHistoryNew.setCreatedGUID(authenticationUser.getUserId());
            opTelViewHistoryNew.setCreatedName(authenticationUser.getUserName());
            opTelViewHistoryDao.insert(opTelViewHistoryNew);
        } else {
            OpTelViewHistory opTelViewHistory = opTelViewHistories.get(0);
            opTelViewHistory.setViewTimes(opTelViewHistory.getViewTimes() + 1);
            opTelViewHistoryDao.updateById(opTelViewHistory);
        }
    }

    public List<PickContactsDto> getContacts(GetDeveloperContactsRequestDto getDeveloperContactsRequestDto) {
        Set<String> mobileSet = new HashSet<>();
        SqlApiListResponseDto sqlApiResponseDto;
        if (getDeveloperContactsRequestDto.getProvince_code() == null || getDeveloperContactsRequestDto.getProvince_code().equals("")) {
            getDeveloperContactsRequestDto.setProvince_code("1");
        }
        if (getDeveloperContactsRequestDto.getSupplier_organizing_code() != null && getDeveloperContactsRequestDto.getSupplier_organizing_code().length() > 0) {
            sqlApiResponseDto = getDeveloperDataService.getSupplierRelatedContacts(getDeveloperContactsRequestDto);
        } else {
            sqlApiResponseDto = getDeveloperDataService.getDeveloperRelatedContacts(getDeveloperContactsRequestDto);
        }

        if (sqlApiResponseDto.getData() != null && sqlApiResponseDto.getData().size() > 0) {
            sqlApiResponseDto.getData().forEach(pc -> {
                if (pc.get("contact_tel") != null) mobileSet.add(pc.get("contact_tel").toString());
            });
        }

        // 取商机自己的联系方式
        List<Map<String, Object>> pContacts = new ArrayList<>();
        if (getDeveloperContactsRequestDto.getPurchase_id() != null && getDeveloperContactsRequestDto.getPurchase_id().length() > 0) {
            Set<String> purchaseId = new HashSet<>();
            purchaseId.add(getDeveloperContactsRequestDto.getPurchase_id());
            pContacts = developerContactService.getPurchaseContacts(purchaseId);
        }

        // 获取联系人历史
        Set<String> mobiles = getPurchaseMobile(sqlApiResponseDto, pContacts);
        Map<String, OpTelViewHistory> opTelViewHistoryMap = getTelViewHistories(mobileSet);

        List<PickContactsDto> pickedContacts = new ArrayList<>();
        pContacts.forEach(pc -> {
            PickContactsDto contactsDto = new PickContactsDto();
            contactsDto.setCompany(pc.get("developer_name").toString());
            contactsDto.setWeight(200);
            contactsDto.setOwner(pc.get("name").toString());
            if (pc.get("name") != null && pc.get("name").toString().length() >= 1) {
                contactsDto.setFirst_name(pc.get("name").toString().substring(0, 1));
            }
            contactsDto.setMobile(pc.get("mobile").toString());
            if (pc.get("mobile") != null && pc.get("mobile").toString().length() > 7) {
                contactsDto.setMobile_hide(pc.get("mobile").toString().substring(0, 3) + "****" + pc.get("mobile").toString().substring(7));
            }
            contactsDto.setCompany_category("开发商");
            contactsDto.setUpdated_time(pc.get("created_at").toString());
            contactsDto.setId(pc.get("uid").toString());

            pickedContacts.add(contactsDto);


        });

        if (sqlApiResponseDto.getData() != null && sqlApiResponseDto.getData().size() > 0) {
            sqlApiResponseDto.getData().forEach(pc -> {
                PickContactsDto contactsDto = makeContact(pc);
                pickedContacts.add(contactsDto);
            });
        }

        Collections.sort(pickedContacts);
        loadTelViewHistory(pickedContacts, opTelViewHistoryMap);
        return pickedContacts;
    }

    public PickContactsDto getContactMobile(GetDetailDataRequestDto dto) {
        GetDeveloperContactsRequestDto getDeveloperContactsRequestDto = new GetDeveloperContactsRequestDto();
        getDeveloperContactsRequestDto.setId(dto.getId());
        SqlApiResponseDto sqlApiResponseDto = getDeveloperDataService.getDeveloperContacts(getDeveloperContactsRequestDto);
        PickContactsDto pickedContact = new PickContactsDto();
        if (sqlApiResponseDto.getData().getRows().size() > 0) {
            sqlApiResponseDto.getData().getRows().forEach(m -> {
                if (m.get("contact_person") != null) {
                    pickedContact.setOwner(m.get("contact_person").toString());
                }
                if (m.get("contact_tel") != null) {
                    pickedContact.setMobile(m.get("contact_tel").toString());
                }
                if (m.get("company_category") != null) {
                    pickedContact.setCompany_category(m.get("company_category").toString());
                }
                if (m.get("updated_time") != null) {
                    pickedContact.setUpdated_time(m.get("updated_time").toString());
                }
                if (m.get("id") != null) {
                    pickedContact.setId(m.get("id").toString());
                }

            });

        } else {
            Map<String, Object> pContacts = developerContactService.getContactInfoByUid(dto.getId());
            if (pContacts != null) {
                if (pContacts.get("ower") != null) {
                    pickedContact.setOwner(pContacts.get("ower").toString());
                }
                if (pContacts.get("ower_mobile") != null) {
                    pickedContact.setMobile(pContacts.get("ower_mobile").toString());
                }
                pickedContact.setCompany_category("开发商");
                if (pContacts.get("created_at") != null) {
                    pickedContact.setUpdated_time(pContacts.get("created_at").toString());
                }
                if (pContacts.get("id") != null) {
                    pickedContact.setId(pContacts.get("uid").toString());
                }
            }
        }
        if (pickedContact.getId() == null) {
            logUtil.error("线索雷达联系人", new Exception("找不到" + dto.getId() + "对应的联系人"));
        }
        return pickedContact;
    }

    public Map<String, Integer> getContactCount(GetDeveloperContactsRequestDto getDeveloperContactsRequestDto) {
        Map<String, Integer> contactCount = new HashMap<>();
        SqlApiListResponseDto sqlApiResponseDto;
        if (getDeveloperContactsRequestDto.getProvince_code() == null || getDeveloperContactsRequestDto.getProvince_code().equals("")) {
            getDeveloperContactsRequestDto.setProvince_code("1");
        }
        if (getDeveloperContactsRequestDto.getSupplier_organizing_code() != null && getDeveloperContactsRequestDto.getSupplier_organizing_code().length() > 0) {
            sqlApiResponseDto = getDeveloperDataService.getSupplierRelatedContacts(getDeveloperContactsRequestDto);
        } else {
            sqlApiResponseDto = getDeveloperDataService.getDeveloperRelatedContacts(getDeveloperContactsRequestDto);
        }

        if (sqlApiResponseDto.getData() == null || sqlApiResponseDto.getData().size() <= 0) {
            return contactCount;
        }

        // 取商机自己的联系方式
        sqlApiResponseDto.getData().forEach(p -> {
            String organizingCode;
            if (p.get("developer_organizing_code") != null && !p.get("developer_organizing_code").equals("")) {
                organizingCode = p.get("developer_organizing_code").toString();
            } else if (p.get("supplier_organizing_code") != null && !p.get("supplier_organizing_code").equals("")) {
                organizingCode = p.get("supplier_organizing_code").toString();
            } else {
                organizingCode = "";
            }

            if (!organizingCode.equals("")) {
                if (contactCount.containsKey(organizingCode)) {
                    Integer num = contactCount.get(organizingCode);
                    contactCount.put(organizingCode, num + 1);
                } else {
                    contactCount.put(organizingCode, 1);
                }

            }

        });

        return contactCount;
    }

    public FieldsSetting loadContactFields() {
        FieldsSetting fieldsSetting = new FieldsSetting();
        fieldsSetting.setIdField("uid");
        fieldsSetting.setFields(new ArrayList<>());
        String groupName = "province_radar_contact";

        fieldsSetting.getFields().add(new DataApiField("owner", groupName, "联系人名称", FieldType.String));
        fieldsSetting.getFields().add(new DataApiField("first_name", groupName, "姓氏", FieldType.String));
        fieldsSetting.getFields().add(new DataApiField("mobile", groupName, "手机号", FieldType.String));
        fieldsSetting.getFields().add(new DataApiField("supplier_organizing_code", groupName, "供应商信仰代码", FieldType.String));
        fieldsSetting.getFields().add(new DataApiField("company", groupName, "公司名称", FieldType.String));
        fieldsSetting.getFields().add(new DataApiField("company_category", groupName, "公司类型", FieldType.String));
        fieldsSetting.getFields().add(new DataApiField("weight", groupName, "权重", FieldType.Int));
        fieldsSetting.getFields().add(new DataApiField("viewTimes", groupName, "查看次数", FieldType.Int));
        fieldsSetting.getFields().add(new DataApiField("updated_time", groupName, "更新时间", FieldType.String));
        fieldsSetting.getFields().add(new DataApiField("mobile_hide", groupName, "手机号(加码)", FieldType.String));
        return fieldsSetting;
    }

    public ListDataResult loadContactData(LoadDataParams options) {
        GetDeveloperContactsRequestDto dto = new GetDeveloperContactsRequestDto();
        dto.addFilterByLoadDataApi(options.getOptions().getFilters());
        dto.setPageSize(2000);
        List<PickContactsDto> res = this.getContacts(dto);
        res.forEach(p -> {
            p.setUid(UUID.randomUUID());
        });
        ListDataResult result = new ListDataResult();
        if (res.size() == 0) {
            result.setData(new ArrayList<>());
            result.setTotal(0);
            return result;
        }
        result.setData(res);
        result.setTotal(res.size());
        return result;
    }
}
